---
title: Use a Struct in Storage
slug: /how-to-guides/v3/pallet-design/storage-value
keywords: pallet design, intermediate, runtime
version: '3.0'
section: how to guides
category: pallet design
---

<Objectives
  data={[
    {
      title: 'Goal',
      description:
        'Use a [`StorageValue`](/rustdocs/latest/frame_support/storage/trait.StorageValue.html) struct and use it in `on_initialize`.',
    },
    {
      title: 'Use Cases',
      description: `Keep track of different accounts and balances for testing a pallet.`,
    },
    {
      title: 'Overview',
      description: `Creating a struct of similarly grouped storage items is a neat way to keep track of them.
		They can be easier to reference than keeping individual \`StorageValue\` items separate this way.
		In addition, they can be used to ease testing and genesis configuration.
		This guide steps through the procedure of creating a struct in storage which:
- Keeps track of an initial amount (\`issuance\`)
- Keeps track of the account that receives that amount (\`minter\`)
- Keeps track of an account that can burn some amount (\`burner\`)
- Is (partially) used in \`on_initialize\``,
    },
  ]}
/>

## Steps

### 1. Create a your struct

Call it `MetaData` and declare its different types:

```rust
#[derive(Clone, Encode, Decode, Eq, PartialEq, RuntimeDebug, Default)]
pub struct MetaData<AccountId, Balance> {
	issuance: Balance,
	minter: AccountId,
	burner: AccountId,
}
```

### 2. Declare the struct as a storage item

Use `StorageValue` to declare the struct as a new single item in storage:

```rust
#[pallet::storage]
#[pallet::getter(fn meta_data)]
pub(super) type MetaDataStore<T: Config> = StorageValue<_, MetaData<T::AccountId, T::Balance>, ValueQuery>;
```

### 3. Configure `GenesisConfig` and `GenesisBuild`

#### `GenesisConfig`

Use `#[pallet::genesis_config]` to declare the admin account that you'll use in your to
initialize values from your `MetaData` struct:

```rust
// Declare `admin` as type `T::AccountId`.
#[pallet::genesis_config]
pub struct GenesisConfig<T: Config> {
	pub admin: T::AccountId,
	}
// Give it a default value.
#[cfg(feature = "std")]
impl<T: Config> Default for GenesisConfig<T> {
	fn default() -> Self {
		Self {
			admin: Default::default(),
			}
		}
	}
```

#### `GenesisBuild`

Use `#[pallet::genesis_build]` to initialize the values of your struct, using `admin` to initialize the values
of type `T::AccountId`:

```rust
#[pallet::genesis_build]
impl<T: Config> GenesisBuild<T> for GenesisConfig<T> {
	fn build(&self) {
		MetaDataStore::<T>::put(MetaData {
			issuance: Zero::zero(),
			minter: self.admin.clone(),
			burner: self.admin.clone(),
		});
	}
}
```

### 4. Use the struct in `on_initialize()`

Assign an amount to the `issuance` field of `MetaData` to be initialized when the chain is launched:

```rust
fn on_initialize(_n: T::BlockNumber) -> Weight {
	let mut meta = MetaDataStore::<T>::get();
	let value: T::Balance = 50u8.into();
	meta.issuance = meta.issuance.saturating_add(value);

	// Add the amount to the `minter` account in storage.
	Accounts::<T>::mutate(&meta.minter, |bal| {
		*bal = bal.saturating_add(value);
	});
}
```

## Examples

- [`reward-coin`](https://github.com/substrate-developer-hub/substrate-how-to-guides/blob/d3602a66d66be5b013f2e3330081ea4e0d6dd978/example-code/template-node/pallets/reward-coin/src/lib.rs#L24-L29) example pallet

## Resources

#### Rust docs

- [`Default::default()`](/rustdocs/latest/sp_std/default/trait.Default.html)
